﻿using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.IO;

public class TextIcon : Text
{
    /// <summary>
    /// 缩放size
    /// </summary>
    private const float ICON_SCALE_OF_DOUBLE_SYMBOLE = 1.0f;
    public override float preferredWidth => cachedTextGeneratorForLayout.GetPreferredWidth(emojiText, GetGenerationSettings(rectTransform.rect.size)) / pixelsPerUnit;
    public override float preferredHeight => cachedTextGeneratorForLayout.GetPreferredHeight(emojiText, GetGenerationSettings(rectTransform.rect.size)) / pixelsPerUnit;
    private Dictionary<string, TextIconConfig> _config = null;
    private const string iconType = "{[a-z0-9A-Z]+}";
    private string emojiText => Regex.Replace(text, iconType, "%%");

    /// <summary>
    /// 基础富文本正则
    /// </summary>
    private static readonly Regex otherRegex = new Regex("<.+?>", RegexOptions.Singleline);

    readonly UIVertex[] m_TempVerts = new UIVertex[4];

    protected override void OnPopulateMesh(VertexHelper toFill)
    {
        if (font == null)
        {
            return;
        }

        Dictionary<int, TextIconConfig> emojiDic = new Dictionary<int, TextIconConfig>();
        if (_config == null)
        {

            // 加载图文混排数据
            _config = new Dictionary<string, TextIconConfig>();
            StreamReader sr = new StreamReader("Assets/TextIcon/Data/Icon_Data.txt");
            string content = sr.ReadToEnd();
            sr.Close();
            sr.Dispose();
            string[] lines = content.Split('\n');
            for (int i = 1; i < lines.Length; i++)
            {
                if (!string.IsNullOrEmpty(lines[i]))
                {
                    string[] strs = lines[i].Split('\t');
                    _config.Add(strs[0], new TextIconConfig(float.Parse(strs[2]), float.Parse(strs[3]), float.Parse(strs[4])));
                }
            }
        }

        if (supportRichText)
        {
            int nParcedCount = 0;
            //[1] [123] 替换成#的下标偏移量			
            int nOffset = 0;
            MatchCollection matches = Regex.Matches(text, iconType);
            TextIconConfig info;
            int orginIndex = 0;
            int lastIndex = 0;
            int otherLength = 0;
            for (int i = 0; i < matches.Count; i++)
            {
                if (_config.TryGetValue(matches[i].Value, out info))
                {
                    orginIndex = 0;
                    lastIndex = 0;
                    orginIndex = matches[i].Index;
                    // 计算富文本长度
                    otherLength = 0;
                    foreach (var item in otherRegex.Matches(text.Substring(lastIndex, orginIndex)))
                    {
                        otherLength += item.ToString().Length;
                    }

                    emojiDic.Add(matches[i].Index - otherLength - nOffset + nParcedCount, info);
                    nOffset += matches[i].Length - 1;
                    nParcedCount++;
                    lastIndex = orginIndex;
                }
            }

        }

        // We don't care if we the font Texture changes while we are doing our Update.
        // The end result of cachedTextGenerator will be valid for this instance.
        // Otherwise we can get issues like Case 619238.
        m_DisableFontTextureRebuiltCallback = true;



        Vector2 extents = rectTransform.rect.size;

        var settings = GetGenerationSettings(extents);
        cachedTextGenerator.Populate(emojiText, settings);




        Rect inputRect = rectTransform.rect;

        // get the text alignment anchor point for the text in local space
        Vector2 textAnchorPivot = GetTextAnchorPivot(alignment);
        Vector2 refPoint = Vector2.zero;
        refPoint.x = Mathf.Lerp(inputRect.xMin, inputRect.xMax, textAnchorPivot.x);
        refPoint.y = Mathf.Lerp(inputRect.yMin, inputRect.yMax, textAnchorPivot.y);

        // Apply the offset to the vertices
        IList<UIVertex> verts = cachedTextGenerator.verts;
        float unitsPerPixel = 1 / pixelsPerUnit;
        int vertCount = verts.Count;

        // We have no verts to process just return (case 1037923)
        if (vertCount <= 0)
        {
            toFill.Clear();
            return;
        }

        Vector2 roundingOffset = new Vector2(verts[0].position.x, verts[0].position.y) * unitsPerPixel;
        roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset;
        toFill.Clear();
        if (roundingOffset != Vector2.zero)
        {
            for (int i = 0; i < vertCount; ++i)
            {
                int tempVertsIndex = i & 3;
                m_TempVerts[tempVertsIndex] = verts[i];
                m_TempVerts[tempVertsIndex].position *= unitsPerPixel;
                m_TempVerts[tempVertsIndex].position.x += roundingOffset.x;
                m_TempVerts[tempVertsIndex].position.y += roundingOffset.y;
                if (tempVertsIndex == 3)
                {
                    toFill.AddUIVertexQuad(m_TempVerts);
                }
            }
        }
        else
        {
            for (int i = 0; i < vertCount; ++i)
            {
                TextIconConfig info;
                int index = i / 4;
                if (emojiDic.TryGetValue(index, out info))
                {
                    //compute the distance of '[' and get the distance of emoji 
                    //计算2个%%的距离
                    float emojiSize = 2 * (verts[i + 1].position.x - verts[i].position.x) * ICON_SCALE_OF_DOUBLE_SYMBOLE;

                    float fCharHeight = verts[i + 1].position.y - verts[i + 2].position.y;
                    float fCharWidth = verts[i + 1].position.x - verts[i].position.x;

                    float fHeightOffsetHalf = (emojiSize - fCharHeight) * 0.5f;
                    float fStartOffset = emojiSize * (1 - ICON_SCALE_OF_DOUBLE_SYMBOLE);

                    m_TempVerts[3] = verts[i];//1
                    m_TempVerts[2] = verts[i + 1];//2
                    m_TempVerts[1] = verts[i + 2];//3
                    m_TempVerts[0] = verts[i + 3];//4

                    m_TempVerts[0].position += new Vector3(fStartOffset, -fHeightOffsetHalf, 0);
                    m_TempVerts[1].position += new Vector3(fStartOffset - fCharWidth + emojiSize, -fHeightOffsetHalf, 0);
                    m_TempVerts[2].position += new Vector3(fStartOffset - fCharWidth + emojiSize, fHeightOffsetHalf, 0);
                    m_TempVerts[3].position += new Vector3(fStartOffset, fHeightOffsetHalf, 0);

                    m_TempVerts[0].position *= unitsPerPixel;
                    m_TempVerts[1].position *= unitsPerPixel;
                    m_TempVerts[2].position *= unitsPerPixel;
                    m_TempVerts[3].position *= unitsPerPixel;

                    float pixelOffset = emojiDic[index].size / 32 / 2;
                    m_TempVerts[0].uv0 = new Vector2(emojiDic[index].x + pixelOffset, emojiDic[index].y + pixelOffset);
                    m_TempVerts[1].uv0 = new Vector2(emojiDic[index].x - pixelOffset + emojiDic[index].size, emojiDic[index].y + pixelOffset);
                    m_TempVerts[2].uv0 = new Vector2(emojiDic[index].x - pixelOffset + emojiDic[index].size, emojiDic[index].y - pixelOffset + emojiDic[index].size);
                    m_TempVerts[3].uv0 = new Vector2(emojiDic[index].x + pixelOffset, emojiDic[index].y - pixelOffset + emojiDic[index].size);

                    toFill.AddUIVertexQuad(m_TempVerts);
                    i += 4 * 2 - 1;
                }
                else
                {
                    int tempVertsIndex = i & 3;
                    m_TempVerts[tempVertsIndex] = verts[i];
                    m_TempVerts[tempVertsIndex].position *= unitsPerPixel;
                    //用color的alpha用来区分是文字还是图片
                    m_TempVerts[tempVertsIndex].color.a = (byte)0;
                    if (tempVertsIndex == 3)
                    {
                        toFill.AddUIVertexQuad(m_TempVerts);
                    }
                }
            }

        }
        m_DisableFontTextureRebuiltCallback = false;
    }
}

/// <summary>
/// 图文混排数据
/// </summary>
public class TextIconConfig
{
    public float x;
    public float y;
    public float size;

    public TextIconConfig(float x, float y, float size)
    {
        this.x = x;
        this.y = y;
        this.size = size;
    }
}